﻿using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Newtonsoft.Json;

namespace Ecobee.Net
{
	/// <summary>
	/// The runtime object represents the last known thermostat running state. This state is composed from 
	/// the last interval status message received from a thermostat. It is also updated each time the 
	/// thermostat posts configuration changes to the server. The runtime object is read-only.
	/// </summary>
	public class Runtime : ApiObject
	{
		#region Private Fields
		private string _key = string.Empty;
		private Revision _revision = new Revision();
		private bool _connected = false;
		private DateTime? _firstConnected = null;
		private DateTime? _connectDateTime = null;
		private DateTime? _disconnectDateTime = null;
		private DateTime? _lastModified = null;
		private DateTime? _lastStatusModified = null;
		private ApiTemperature _actualTemperature = ApiTemperature.Empty;
		private float? _actualHumidity = null;
		private ApiTemperature _desiredHeat = ApiTemperature.Empty;
		private ApiTemperature _desiredCool = ApiTemperature.Empty;
		private float? _desiredHumidity = null;
		private float? _desiredDehumidity = null;
		private FanMode? _desiredFanMode = null;
		#endregion

		/// <summary>
		/// Gets a System.String object that represents a unique identifier for
		/// this instance of Ecobee.Net.Runtime.
		/// </summary>
		[JsonIgnore]
		public override string UniqueKey
		{
			get
			{
				return this.Revision.Identifier;
			}
		}

		/// <summary>
		///  The current runtime revision. Equivalent in meaning to the runtime revision 
		///  number in the thermostat summary call.
		/// </summary>
		[JsonProperty(PropertyName = "revision", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValueConverter(typeof(Revision), typeof(RevisionDefaultConverter), "")]
		public Revision Revision
		{
			get
			{
				return _revision;
			}
			set
			{
				_revision = value;
			}
		}

		/// <summary>
		/// Whether the thermostat is currently connected to the server.
		/// </summary>
		[JsonProperty(PropertyName = "connected", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(false)]
		public bool Connected
		{
			get
			{
				return _connected;
			}
			set
			{
				_connected = value;
			}
		}

		/// <summary>
		/// The UTC date/time stamp of when the thermostat first connected to the ecobee server.
		/// </summary>
		[JsonProperty(PropertyName = "firstConnected", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public DateTime? FirstConnected
		{
			get
			{
				return _firstConnected;
			}
			set
			{
				_firstConnected = value;
			}
		}

		/// <summary>
		/// The last recorded connection date and time. 
		/// </summary>
		[JsonProperty(PropertyName = "connectDateTime", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public DateTime? ConnectDateTime
		{
			get
			{
				return _connectDateTime;
			}
			set
			{
				_connectDateTime = value;
			}
		}

		/// <summary>
		/// The last recorded disconnection date and time.
		/// </summary>
		[JsonProperty(PropertyName = "disconnectDateTime", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public DateTime? DisconnectDateTime
		{
			get
			{
				return _disconnectDateTime;
			}
			set
			{
				_disconnectDateTime = value;
			}
		}

		/// <summary>
		/// The UTC date/time stamp of when the thermostat was updated. Format: YYYY-MM-DD HH:MM:SS.
		/// </summary>
		[JsonProperty(PropertyName = "lastModified", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public DateTime? LastModified
		{
			get
			{
				return _lastModified;
			}
			set
			{
				_lastModified = value;
			}
		}

		/// <summary>
		/// The UTC date/time stamp of when the thermostat last posted its runtime information. Format: YYYY-MM-DD HH:MM:SS.
		/// </summary>
		[JsonProperty(PropertyName = "lastStatusModified", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public DateTime? LastStatusModified
		{
			get
			{
				return _lastStatusModified;
			}
			set
			{
				_lastStatusModified = value;
			}
		}

		/// <summary>
		/// The current temperature displayed on the thermostat.
		/// </summary>
		[JsonProperty(PropertyName = "actualTemperature", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValueConverter(typeof(ApiTemperature), typeof(ApiTemperatureDefaultConverter), 0F)]
		public ApiTemperature ActualTemperature
		{
			get
			{
				return _actualTemperature;
			}
			set
			{
				_actualTemperature = value;
			}
		}

		/// <summary>
		/// The current humidity % shown on the thermostat.
		/// </summary>
		[JsonProperty(PropertyName = "actualHumidity", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public float? ActualHumidity
		{
			get
			{
				return _actualHumidity;
			}
			set
			{
				_actualHumidity = value;
			}
		}

		/// <summary>
		/// The desired heat temperature as per the current running program or active event.
		/// </summary>
		[JsonProperty(PropertyName = "desiredHeat", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValueConverter(typeof(ApiTemperature), typeof(ApiTemperatureDefaultConverter), 0F)]
		public ApiTemperature DesiredHeat
		{
			get
			{
				return _desiredHeat;
			}
			set
			{
				_desiredHeat = value;
			}
		}

		/// <summary>
		/// The desired cool temperature as per the current running program or active event.
		/// </summary>
		[JsonProperty(PropertyName = "desiredCool", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValueConverter(typeof(ApiTemperature), typeof(ApiTemperatureDefaultConverter), 0F)]
		public ApiTemperature DesiredCool
		{
			get
			{
				return _desiredCool;
			}
			set
			{
				_desiredCool = value;
			}
		}

		/// <summary>
		/// The desired humidity set point.
		/// </summary>
		[JsonProperty(PropertyName = "desiredHumidity", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public float? DesiredHumidity
		{
			get
			{
				return _desiredHumidity;
			}
			set
			{
				_desiredHumidity = value;
			}
		}

		/// <summary>
		/// The desired dehumidification set point.
		/// </summary>
		[JsonProperty(PropertyName = "desiredDehumidity", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public float? DesiredDehumidity
		{
			get
			{
				return _desiredDehumidity;
			}
			set
			{
				_desiredDehumidity = value;
			}
		}

		/// <summary>
		/// The desired fan mode. Values: auto, on or null if the HVAC system is off. 
		/// </summary>
		[JsonProperty(PropertyName = "desiredFanMode", DefaultValueHandling = DefaultValueHandling.Ignore)]
		[DefaultValue(null)]
		public FanMode? DesiredFanMode
		{
			get
			{
				return _desiredFanMode;
			}
			set
			{
				_desiredFanMode = value;
			}
		}

		/// <summary>
		/// Determines whether this instance and a specified object, which must also
		/// be a Ecobee.Net.Runtime object, have the same value.
		/// </summary>
		/// <param name="obj"></param>
		/// <returns></returns>
		public override bool Equals(object obj)
		{
			bool returnValue = false;

			if (obj is Runtime)
			{
				returnValue = (this.UniqueKey == ((Runtime)obj).UniqueKey);
			}

			return returnValue;
		}

		/// <summary>
		/// Gets a unique hash value for this instance of Ecobee.Net.Runtime.
		/// </summary>
		/// <returns></returns>
		public override int GetHashCode()
		{
			return RuntimeHelpers.GetHashCode(this);
		}
	}
}
